home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / SNNSV32.ZIP / SNNSv3.2 / kernel / sources / kr_mem.c < prev    next >
C/C++ Source or Header  |  1994-04-25  |  47KB  |  1,822 lines

  1. /*****************************************************************************
  2.   FILE           : kr_mem.c
  3.   SHORTNAME      : 
  4.   SNNS VERSION   : 3.2
  5.  
  6.   PURPOSE        : SNNS-Kernel Memory Manager 
  7.   NOTES          :
  8.  
  9.   AUTHOR         : Niels Mache
  10.   DATE           : 21.2.90
  11.  
  12.   CHANGED BY     : Sven Doering
  13.   IDENTIFICATION : @(#)kr_mem.c    1.19 4/7/94
  14.   SCCS VERSION   : 1.19
  15.   LAST CHANGE    : 4/7/94
  16.  
  17.              Copyright (c) 1990-1994  SNNS Group, IPVR, Univ. Stuttgart, FRG
  18.  
  19. ******************************************************************************/
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <memory.h>
  24. #include <values.h>
  25.  
  26.  
  27. #include "kr_typ.h"     /*  Kernel Types and Constants  */
  28. #include "kernel.h"
  29. #include "kr_const.h"     /*  Constant Declarators for SNNS-Kernel  */
  30. #include "kr_def.h"     /*  Default Values  */
  31.  
  32. #include "kr_mem.ph"     /*  Function prototypes  */
  33. #include "kr_mac.h"     /*  Kernel Macros  */
  34.  
  35. /*  ULTRIX-32 Operating System */
  36. #if defined (ultrix) || defined (__BORLANDC__) 
  37. #include "strdup.h"    /*  include strdup function because strdup is
  38.                 missing in ULTRIX-32  */
  39. #endif
  40.  
  41.  
  42.  
  43.  
  44. /*****************************************************************************
  45.   FUNCTION : krm_allocLinks
  46.  
  47.   PURPOSE  : allocate another link array (with size N entries)
  48.   NOTES    :
  49.  
  50.   RETURNS  :
  51.   UPDATE   : 
  52. ******************************************************************************/
  53. static  int     krm_allocLinks(int N)
  54. {
  55.   LinkArray     tmp_ptr;
  56.  
  57.  
  58.   tmp_ptr = (LinkArray) calloc((unsigned int)( N + 1), LINK_SIZE );
  59.   if (tmp_ptr == NULL)  return( 1 );
  60.  
  61.   if (link_array == NULL)
  62.     {
  63.     tmp_ptr->next = NULL;           /*  free link/block sentinel
  64.                                     */
  65.     free_link_ptr = tmp_ptr;
  66.     }
  67.   else
  68.     {
  69.     tmp_ptr->next = link_block_list;
  70.     }
  71.  
  72.   link_block_list = tmp_ptr;    /* free link block sentinel */
  73.   NoOfAllocLinks += N;
  74.   link_array = tmp_ptr;         /* link_array points to the first link entry */
  75.   return( 0 );
  76. }
  77.  
  78.  
  79. /*****************************************************************************
  80.   FUNCTION : krm_getLink
  81.  
  82.   PURPOSE  : get one link structure
  83.   NOTES    :
  84.  
  85.   RETURNS  :
  86.   UPDATE   : 
  87. ******************************************************************************/
  88. struct Link  *krm_getLink(void)
  89. {
  90.   struct Link   *tmp_ptr;
  91.  
  92.  
  93.   if ((NoOfLinks == NoOfAllocLinks) || (link_array == NULL))
  94.     if (krm_allocLinks( LINK_BLOCK ) != 0)
  95.       {  /*  memory allocation failed  */
  96.       KernelErrorCode = KRERR_INSUFFICIENT_MEM;
  97.       return( NULL );
  98.     }
  99.  
  100.   NoOfLinks++;
  101.  
  102.   if (free_link_ptr->next != NULL)
  103.     {
  104.     tmp_ptr = free_link_ptr;
  105.     free_link_ptr = free_link_ptr->next;
  106.   }
  107.   else
  108.     {
  109.     tmp_ptr = ++link_array;
  110.   }
  111.  
  112.   return( tmp_ptr );
  113. }
  114.  
  115.  
  116. /*****************************************************************************
  117.   FUNCTION : krm_releaseLink
  118.  
  119.   PURPOSE  : release one link structure
  120.   NOTES    :
  121.  
  122.   RETURNS  :
  123.   UPDATE   : 
  124. ******************************************************************************/
  125. void    krm_releaseLink(struct Link *link_ptr)
  126. {
  127.   --NoOfLinks;
  128.  
  129.   link_ptr->next = free_link_ptr;
  130.   free_link_ptr  = link_ptr;
  131. }
  132.  
  133.  
  134. /*****************************************************************************
  135.   FUNCTION : krm_releaseAllLinks
  136.  
  137.   PURPOSE  : release the link and all following links
  138.   NOTES    :
  139.  
  140.   RETURNS  :
  141.   UPDATE   : 
  142. ******************************************************************************/
  143. void    krm_releaseAllLinks(struct Link *first_link_ptr)
  144. {
  145.   struct Link  *curr,
  146.                *next,
  147.                *free;
  148.  
  149.  
  150.   free = free_link_ptr;
  151.   curr = first_link_ptr;
  152.  
  153.   while (curr != NULL)  {
  154.     --NoOfLinks;
  155.  
  156.     next = curr->next;
  157.     curr->next = free;
  158.  
  159.     free = curr;
  160.     curr = next;
  161.   }
  162.  
  163.   free_link_ptr = free;
  164. }
  165.  
  166.  
  167. /*****************************************************************************
  168.   FUNCTION : krm_releaseLinkArrays
  169.  
  170.   PURPOSE  : free all link array
  171.   NOTES    :
  172.  
  173.   RETURNS  :
  174.   UPDATE   : 
  175. ******************************************************************************/
  176. void  krm_releaseLinkArrays(void)
  177. {
  178.   register struct Link  *tmp_ptr1, *tmp_ptr2;
  179.  
  180.  
  181.   NoOfLinks = NoOfAllocLinks = 0;
  182.  
  183.   if (link_array != NULL)  {
  184.     tmp_ptr2 = link_block_list;
  185.     while (tmp_ptr2 != NULL)  {
  186.       tmp_ptr1 = tmp_ptr2->next;
  187.       free( (char *) tmp_ptr2 );
  188.       tmp_ptr2 = tmp_ptr1;
  189.     }
  190.  
  191.     free_link_ptr = link_array = NULL;
  192.   }
  193. }
  194.  
  195.  
  196.  
  197. /*#################################################
  198.  
  199. GROUP: Site Functions
  200.  
  201. #################################################*/
  202. /*****************************************************************************
  203.   FUNCTION : krm_allocSites
  204.  
  205.   PURPOSE  : allocate another site array (with size N entries)
  206.   NOTES    :
  207.  
  208.   RETURNS  :
  209.   UPDATE   : 
  210. ******************************************************************************/
  211. static  int     krm_allocSites(int N)
  212. {
  213.   SiteArray     tmp_ptr;
  214.  
  215.  
  216.   tmp_ptr = (SiteArray) calloc((unsigned int)(N + 1), SITE_SIZE );
  217.   if (tmp_ptr == NULL)  return( 1 );
  218.  
  219.   if (site_array == NULL)  {
  220.     tmp_ptr->next = NULL;           /*  free site/block sentinel   */
  221.     free_site_ptr = tmp_ptr;
  222.   }
  223.   else  {
  224.     tmp_ptr->next = site_block_list;
  225.   }
  226.  
  227.   site_block_list = tmp_ptr;    /*  free site block sentinel  */
  228.   NoOfAllocSites += N;
  229.   site_array = tmp_ptr;         /*  site_array points to the sentinel */
  230.   return( 0 );
  231. }
  232.  
  233.  
  234. /*****************************************************************************
  235.   FUNCTION : krm_getSite
  236.  
  237.   PURPOSE  : get one unit-site structure
  238.   NOTES    :
  239.  
  240.   RETURNS  :
  241.   UPDATE   : 
  242. ******************************************************************************/
  243. struct Site    *krm_getSite(void)
  244. {
  245.   struct Site   *tmp_ptr;
  246.  
  247.  
  248.   if ((site_array == NULL) || (NoOfSites == NoOfAllocSites))
  249.     if (krm_allocSites( SITE_BLOCK ) != 0)  {
  250.       KernelErrorCode = KRERR_INSUFFICIENT_MEM;
  251.       return( NULL );
  252.     }
  253.  
  254.   NoOfSites++;
  255.   NoOfNetSites++;
  256.  
  257.   if (free_site_ptr->next != NULL)  {
  258.     tmp_ptr = free_site_ptr;
  259.     free_site_ptr = free_site_ptr->next;
  260.   }
  261.   else  {
  262.     tmp_ptr = ++site_array;
  263.   }
  264.  
  265.   return( tmp_ptr );
  266. }
  267.  
  268.  
  269. /*****************************************************************************
  270.   FUNCTION : krm_getFtypeSite
  271.  
  272.   PURPOSE  : get one site structure for functionality use only
  273.   NOTES    :
  274.  
  275.   RETURNS  :
  276.   UPDATE   : 
  277. ******************************************************************************/
  278. static struct Site  *krm_getFtypeSite(void)
  279. {
  280.   struct Site  *tmp_ptr;
  281.  
  282.   KernelErrorCode = KRERR_NO_ERROR;
  283.  
  284.   if ((site_array == NULL) || (NoOfSites == NoOfAllocSites))
  285.     if (krm_allocSites( SITE_BLOCK ) != 0)  {
  286.       KernelErrorCode = KRERR_INSUFFICIENT_MEM;
  287.       return( NULL );
  288.     }
  289.  
  290.   NoOfSites++;
  291.  
  292.   if (free_site_ptr->next != NULL)  {
  293.     tmp_ptr = free_site_ptr;
  294.     free_site_ptr = free_site_ptr->next;
  295.   }
  296.   else  {
  297.     tmp_ptr = ++site_array;
  298.   }
  299.  
  300.   return( tmp_ptr );
  301. }
  302.  
  303.  
  304. /*****************************************************************************
  305.   FUNCTION : krm_releaseSite
  306.  
  307.   PURPOSE  : release one unit-site structure
  308.   NOTES    :
  309.  
  310.   RETURNS  :
  311.   UPDATE   : 
  312. ******************************************************************************/
  313. void    krm_releaseSite(struct Site *site_ptr)
  314. {
  315.   --NoOfSites;
  316.   --NoOfNetSites;
  317.  
  318.   site_ptr->next = free_site_ptr;
  319.   free_site_ptr  = site_ptr;
  320. }
  321.  
  322.  
  323. /*****************************************************************************
  324.   FUNCTION :krm_releaseFtypeSite
  325.  
  326.   PURPOSE  : 
  327.   NOTES    : Future Use: 
  328.              release one Ftype-site structure
  329.  
  330.   RETURNS  :
  331.   UPDATE   : 
  332. ******************************************************************************/
  333. /*
  334. static void    krm_releaseFtypeSite(struct Site *site_ptr )
  335. {
  336.   --NoOfSites;
  337.  
  338.   site_ptr->next = free_site_ptr;
  339.   free_site_ptr  = site_ptr;
  340. }
  341. */
  342.  
  343. /*****************************************************************************
  344.   FUNCTION : krm_releaseAllSites
  345.  
  346.   PURPOSE  : release the unit-site and all following sites (at this unit)
  347.   NOTES    :
  348.  
  349.   RETURNS  :
  350.   UPDATE   : 
  351. ******************************************************************************/
  352. void    krm_releaseAllSites(struct Site *first_site_ptr)
  353. {
  354.   struct Site  *curr,
  355.                *next,
  356.                *free;
  357.  
  358.  
  359.   free = free_site_ptr;
  360.   curr = first_site_ptr;
  361.  
  362.   while (curr != NULL)  {
  363.     --NoOfSites;
  364.     --NoOfNetSites;
  365.  
  366.     next = curr->next;
  367.     curr->next = free;
  368.  
  369.     free = curr;
  370.     curr = next;
  371.   }
  372.  
  373.   free_site_ptr = free;
  374. }
  375.  
  376.  
  377. /*****************************************************************************
  378.   FUNCTION : krm_releaseAllFtypeSites
  379.  
  380.   PURPOSE  : release the Ftype-site and all following sites
  381.   NOTES    :
  382.  
  383.   RETURNS  :
  384.   UPDATE   : 
  385. ******************************************************************************/
  386. static void    krm_releaseAllFtypeSites(struct Site *first_site_ptr)
  387. {
  388.   struct Site  *curr,
  389.                *next,
  390.                *free;
  391.  
  392.  
  393.   free = free_site_ptr;
  394.   curr = first_site_ptr;
  395.  
  396.   while (curr != NULL)  {
  397.     --NoOfSites;
  398.  
  399.     next = curr->next;
  400.     curr->next = free;
  401.  
  402.     free = curr;
  403.     curr = next;
  404.   }
  405.  
  406.   free_site_ptr = free;
  407. }
  408.  
  409. /*****************************************************************************
  410.   FUNCTION :  krm_releaseSiteArrays
  411.  
  412.   PURPOSE  : free all site arrays
  413.   NOTES    :
  414.  
  415.   RETURNS  :
  416.   UPDATE   : 
  417. ******************************************************************************/
  418. static  void    krm_releaseSiteArrays(void)
  419. {
  420.   struct Site      *tmp_ptr;
  421.  
  422.  
  423.   NoOfSites      = 0;
  424.   NoOfNetSites   = 0;
  425.   NoOfAllocSites = 0;
  426.  
  427.   if (site_array != NULL)  {
  428.     while (site_block_list != NULL)  {
  429.       tmp_ptr =  site_block_list->next;
  430.       free( (char *) site_block_list );
  431.       site_block_list = tmp_ptr;
  432.     }
  433.  
  434.     free_site_ptr = NULL;
  435.     site_array    = NULL;
  436.   }
  437. }
  438.  
  439.  
  440.  
  441. /*#################################################
  442.  
  443. GROUP: Unit Functions
  444.  
  445. #################################################*/
  446. /*****************************************************************************
  447.   FUNCTION : krm_unitArrayGC
  448.  
  449.   PURPOSE  : garbage collection of unit array 
  450.   NOTES    :
  451.  
  452.   RETURNS  :
  453.   UPDATE   : 
  454. ******************************************************************************/
  455. void  krm_unitArrayGC(void)
  456. {
  457.   register struct Link   *link_ptr;
  458.   register struct Site   *site_ptr;
  459.   register struct Unit   *unit_ptr;
  460.   register struct Unit   *new_unit_ptr;
  461.   struct Unit   *dest_unit_ptr;
  462.  
  463.  
  464.   /*  find first unused unit stucture  */
  465.   dest_unit_ptr = NULL;
  466.   FOR_ALL_UNITS( unit_ptr )
  467.     if (!UNIT_IN_USE( unit_ptr ))
  468.       {  /*  unit isn't in use  */
  469.       dest_unit_ptr = unit_ptr;  /*  store the first unused unit stucture  */
  470.       break;
  471.     }
  472.  
  473.   if (dest_unit_ptr != NULL)  
  474.     {  /*  do garbage collection  */
  475.     NetModified = TRUE;
  476.  
  477.     /*  store continous unit pointers in each unit struct  */
  478.     new_unit_ptr = unit_array;
  479.     FOR_ALL_UNITS( unit_ptr )
  480.       if UNIT_IN_USE( unit_ptr )
  481.         /*  unit is in use  */
  482.         unit_ptr->Aux.ptr = (char *) ++new_unit_ptr;
  483.  
  484.     /*  adjust the link pointers  */
  485.     FOR_ALL_UNITS( unit_ptr )
  486.       if UNIT_IN_USE( unit_ptr )  {
  487.     if UNIT_HAS_SITES( unit_ptr )
  488.       FOR_ALL_SITES_AND_LINKS( unit_ptr, site_ptr, link_ptr )
  489.               link_ptr->to = (struct Unit *) link_ptr->to->Aux.ptr;
  490.         else
  491.       if UNIT_HAS_DIRECT_INPUTS( unit_ptr )
  492.         FOR_ALL_LINKS( unit_ptr, link_ptr )
  493.               link_ptr->to = (struct Unit *) link_ptr->to->Aux.ptr;
  494.       }
  495.  
  496.  
  497.     /*  compress unit array  */
  498.     for (unit_ptr = dest_unit_ptr+1; unit_ptr<=unit_array+MaxUnitNo; unit_ptr++)
  499.       if UNIT_IN_USE( unit_ptr )
  500.         memcpy( (char *) dest_unit_ptr++, (char *) unit_ptr, UNIT_SIZE );
  501.  
  502.     MinUnitNo = 1;
  503.     MaxUnitNo = NoOfUnits;
  504.     FreeUnitIndex = 0;
  505.   }
  506.  
  507.   /*  reduce size of unit array, if needed  */
  508.   if ((NoOfAllocUnits - NoOfUnits) >= (2 * UNIT_BLOCK))  {
  509.     unit_ptr = (UnitArray) realloc( (char *) unit_array, (unsigned)
  510.                                    ((NoOfAllocUnits + 1 - UNIT_BLOCK) * 
  511.                     UNIT_SIZE) );
  512.     if (unit_ptr != NULL)  {
  513.       unit_array = unit_ptr;
  514.       NoOfAllocUnits -= UNIT_BLOCK;
  515.     }
  516.   }
  517. }
  518.  
  519.  
  520. /*****************************************************************************
  521.   FUNCTION : krm_relocateLinkPtrs
  522.  
  523.   PURPOSE  : relocate the link pointers. (If the address of the unit array was modified
  524.              because the memory was reallocated, the link pointers must be relocated)
  525.  
  526.   NOTES    :
  527.  
  528.   RETURNS  :
  529.   UPDATE   : 
  530. ******************************************************************************/
  531. static  void    krm_relocateLinkPtrs(int offset)
  532. {
  533.   register struct Link   *link_ptr;
  534.   register struct Site   *site_ptr;
  535.   register struct Unit   *unit_ptr;
  536.  
  537.  
  538.   FOR_ALL_UNITS( unit_ptr )
  539.     if UNIT_IN_USE( unit_ptr )  {
  540.       if UNIT_HAS_SITES( unit_ptr )
  541.     FOR_ALL_SITES_AND_LINKS( unit_ptr, site_ptr, link_ptr )
  542.       link_ptr->to = (struct Unit *) ((char *) link_ptr->to + offset);
  543.       else
  544.     if UNIT_HAS_DIRECT_INPUTS( unit_ptr )
  545.       FOR_ALL_LINKS( unit_ptr, link_ptr )
  546.             link_ptr->to = (struct Unit *) ((char *) link_ptr->to + offset);
  547.     }
  548. }
  549.  
  550.  
  551. /*****************************************************************************
  552.   FUNCTION : krm_allocUnits
  553.  
  554.   PURPOSE  : allocate the unit array
  555.   NOTES    :
  556.  
  557.   RETURNS  :
  558.   UPDATE   : 
  559. ******************************************************************************/
  560. krui_err  krm_allocUnits(int N)
  561. {
  562.   UnitArray  tmp_ptr;
  563.   int  offset;
  564.  
  565.   if ((NoOfAllocUnits - NoOfUnits) < N)
  566.     {  /*  alloc units    */
  567.     N = (N / UNIT_BLOCK + 1) * UNIT_BLOCK;
  568.   }
  569.  
  570.   if (unit_array == NULL)  {
  571.     tmp_ptr = (UnitArray) calloc((unsigned int)( NoOfAllocUnits + N + 1 ), 
  572.                  UNIT_SIZE );
  573.     if (tmp_ptr == NULL)
  574.       {  /*  mem alloc failed     */
  575.       KernelErrorCode = KRERR_INSUFFICIENT_MEM;
  576.       return( KernelErrorCode );
  577.     }
  578.     FreeUnitIndex = 0;
  579.     tmp_ptr[0].Out.nextFreeUnit = 0;   /*  sentinel of free unit list
  580.                                        */
  581.   }
  582.   else  {
  583.     tmp_ptr = (UnitArray) realloc( (char *) unit_array, (unsigned)
  584.                                    ((NoOfAllocUnits + N + 1 ) * UNIT_SIZE) );
  585.     if (tmp_ptr == NULL)
  586.       {  /*  mem alloc failed     */
  587.       KernelErrorCode = KRERR_INSUFFICIENT_MEM;
  588.       return( KernelErrorCode );
  589.     }
  590.     offset = (char *) tmp_ptr - (char *) unit_array;
  591.     if (offset != 0)  krm_relocateLinkPtrs( offset );
  592.   }
  593.  
  594.   NoOfAllocUnits += N;
  595.   unit_array = tmp_ptr;
  596.  
  597.   KernelErrorCode = KRERR_NO_ERROR;
  598.   return( KernelErrorCode );
  599. }
  600.  
  601. /*****************************************************************************
  602.   FUNCTION : krm_getUnit
  603.  
  604.   PURPOSE  : get one unit structure
  605.   NOTES    :
  606.  
  607.   RETURNS  :
  608.   UPDATE   : 
  609. ******************************************************************************/
  610. int  krm_getUnit(void)
  611. {
  612.   register int   unit_no;
  613.  
  614.   KernelErrorCode = KRERR_NO_ERROR;
  615.   if ((unit_array == NULL) || (NoOfUnits == NoOfAllocUnits))
  616.     if (krm_allocUnits( UNIT_BLOCK ) != 0)
  617.       {  /*  Insufficient memory  */
  618.       KernelErrorCode = KRERR_INSUFFICIENT_MEM;
  619.       return( 0 );
  620.     }
  621.   NoOfUnits++;
  622.  
  623.   if (FreeUnitIndex != 0)
  624.     {  /*  reuse unit  */
  625.     unit_no = FreeUnitIndex;
  626.     FreeUnitIndex = unit_array[unit_no].Out.nextFreeUnit;
  627.   }
  628.   else
  629.     unit_no = NoOfUnits;
  630.  
  631.   /*  this unit is ready to use  */
  632.   unit_array[unit_no].flags = UFLAG_IN_USE;
  633.   unit_array[unit_no].sites = NULL;
  634.  
  635.   if (NoOfUnits == 1)
  636.     MinUnitNo = MaxUnitNo = unit_no;
  637.   else  {
  638.     /*    store the highest allocated unit number  */
  639.     if (unit_no > MaxUnitNo)  MaxUnitNo = unit_no;
  640.     /*    store the lowest allocated unit number    */
  641.     if (unit_no < MinUnitNo)  MinUnitNo = unit_no;
  642.   }
  643.  
  644.   return( unit_no );
  645. }
  646.  
  647.  
  648. /*****************************************************************************
  649.   FUNCTION :  krm_releaseUnit
  650.  
  651.   PURPOSE  : release unit
  652.              
  653.   NOTES    : NEW VERSION in SNNS V3.0
  654.              Now the garbage collection is performed on every deletion of 
  655.              a unit.
  656.  
  657.   RETURNS  :
  658.   UPDATE   : 
  659. ******************************************************************************/
  660. void    krm_releaseUnit(int UnitNo)
  661. {
  662.   if (unit_array[UnitNo].flags != UFLAG_FREE) {  /*  don't release twice
  663.                                                  */
  664.     --NoOfUnits;
  665.  
  666.     unit_array[UnitNo].flags = UFLAG_FREE;
  667.  
  668.   }
  669. }
  670.  
  671.  
  672. /*****************************************************************************
  673.   FUNCTION : krm_releaseUnitArrays
  674.  
  675.   PURPOSE  : free the unit array
  676.   NOTES    :
  677.  
  678.   RETURNS  :
  679.   UPDATE   : 
  680. ******************************************************************************/
  681. static    void    krm_releaseUnitArrays(void)
  682. {
  683.   NoOfAllocUnits = FreeUnitIndex =
  684.   NoOfUnits = NoOfInputUnits = NoOfOutputUnits =
  685.   NoOfHiddenUnits = MaxUnitNo = 0;
  686.  
  687.   if (unit_array != NULL)  {
  688.     free( (char *) unit_array );
  689.     unit_array = NULL;
  690.   }
  691. }
  692.  
  693.  
  694.  
  695. /*#################################################
  696.  
  697. GROUP: General Purpose Functions
  698.  
  699. #################################################*/
  700. /*****************************************************************************
  701.   FUNCTION : krm_getMemoryManagerInfo
  702.  
  703.   PURPOSE  : get information about memory usage
  704.   NOTES    :
  705.  
  706.   RETURNS  :
  707.   UPDATE   : 
  708. ******************************************************************************/
  709. void    krm_getMemoryManagerInfo(int *array_size, int info_array[])
  710. {
  711.   info_array[ 0 ] = NoOfNetSites;
  712.  
  713. #ifdef MASPAR_KERNEL
  714.   if (specialNetworkType == NET_TYPE_FF1)
  715.     info_array[ 1 ] = descrFFnet.no_of_weights;
  716.   else
  717.     info_array[ 1 ] = NoOfLinks;
  718. #else
  719.   info_array[ 1 ] = NoOfLinks;
  720. #endif
  721.  
  722.   info_array[ 2 ] = NoOfSTableEntries;
  723.   info_array[ 3 ] = NoOfFTableEntries;
  724.  
  725.   info_array[ 4 ] = NoOfAllocUnits;
  726.   info_array[ 5 ] = NoOfAllocSites;
  727.   info_array[ 6 ] = NoOfAllocLinks;
  728.   info_array[ 7 ] = NoOfAllocNTableEntries;
  729.   info_array[ 8 ] = NoOfAllocSTableEntries;
  730.   info_array[ 9 ] = NoOfFTableEntries;
  731.  
  732.   *array_size = 10;
  733. }
  734.  
  735.  
  736. /*****************************************************************************
  737.   FUNCTION : krm_allocUnitTopoArray
  738.  
  739.   PURPOSE  : allocate the array for topological sorting of the units in the 
  740.              network
  741.   NOTES    :
  742.  
  743.   RETURNS  :
  744.   UPDATE   : 
  745. ******************************************************************************/
  746. krui_err  krm_allocUnitTopoArray(int N)
  747. {
  748.   KernelErrorCode = KRERR_NO_ERROR;  /*  reset return code  */
  749.  
  750.   if (topo_ptr_array != NULL)
  751.     {  /*  reallocate array for topologic sorting  */
  752.     topo_ptr_array = (TopoPtrArray) realloc( (char *) topo_ptr_array,
  753.                          (unsigned) (N * TOPO_PTR_SIZE) );
  754.   }
  755.   else
  756.     {  /*  allocate new array for topologic sorting  */
  757.     topo_ptr_array = (TopoPtrArray) calloc((unsigned int) N, TOPO_PTR_SIZE);
  758.   }
  759.  
  760.   if (topo_ptr_array == NULL)  KernelErrorCode = KRERR_INSUFFICIENT_MEM;
  761.  
  762.   return( KernelErrorCode );
  763. }
  764.  
  765.  
  766. /*****************************************************************************
  767.   FUNCTION : krm_releaseUnitTopoArray
  768.  
  769.   PURPOSE  : release the topolocic array
  770.   NOTES    :
  771.  
  772.   RETURNS  :
  773.   UPDATE   : 
  774. ******************************************************************************/
  775. void  krm_releaseUnitTopoArray(void)
  776. {
  777.   if (topo_ptr_array != NULL)  {
  778.     free( (char *) topo_ptr_array );
  779.     topo_ptr_array = NULL;
  780.   }
  781. }
  782.  
  783.  
  784.  
  785. /*#################################################
  786.  
  787. GROUP: NameTable Functions
  788.  
  789. #################################################*/
  790. /*****************************************************************************
  791.   FUNCTION : krm_allocNTableArray
  792.  
  793.   PURPOSE  : allocate one name-table block
  794.   NOTES    :
  795.  
  796.   RETURNS  :
  797.   UPDATE   : 
  798. ******************************************************************************/
  799. static  int     krm_allocNTableArray(void)
  800. {
  801.   NTableArray     tmp_ptr;
  802.  
  803.  
  804.   tmp_ptr = (NTableArray) calloc( NTABLE_BLOCK + 1, NTABLE_SIZE );
  805.   if (tmp_ptr == NULL)  return( 1 );
  806.  
  807.   if (NTable_array == NULL)  {
  808.     tmp_ptr->Entry.next = NULL;     /*  free name-table block sentinel  */
  809.     free_NTable_entry = tmp_ptr;    /*  free name-table entry sentinel  */
  810.   }
  811.   else  {
  812.     tmp_ptr->Entry.next = NTable_block_list;    /*  append new name-table block
  813.                                                     to block list   */
  814.   }
  815.  
  816.   NTable_block_list = tmp_ptr;      /* update block list ptr */
  817.   NoOfAllocNTableEntries += NTABLE_BLOCK;
  818.   NTable_array = tmp_ptr + 1;       /* NTable_array points to the first entry */
  819.   return( 0 );
  820. }
  821.  
  822.  
  823. /*****************************************************************************
  824.   FUNCTION : krm_getNTableEntry
  825.  
  826.   PURPOSE  : get one name-table entry
  827.   NOTES    :
  828.  
  829.   RETURNS  :
  830.   UPDATE   : 
  831. ******************************************************************************/
  832. static struct NameTable  *krm_getNTableEntry(void)
  833. {
  834.   struct NameTable  *tmp_ptr;
  835.  
  836.  
  837.   if ((NTable_array == NULL) || (NoOfNTableEntries == NoOfAllocNTableEntries))
  838.     if (krm_allocNTableArray() != 0)  {
  839.       KernelErrorCode = KRERR_INSUFFICIENT_MEM;
  840.       return( NULL );
  841.     }
  842.  
  843.   NoOfNTableEntries++;
  844.  
  845.   if (free_NTable_entry->Entry.next != NULL)
  846.     {   /*  a previous released name-table entry is availabe    */
  847.     tmp_ptr = free_NTable_entry;
  848.     free_NTable_entry = free_NTable_entry->Entry.next;
  849.   }
  850.   else  {
  851.     tmp_ptr = NTable_array++;
  852.   }
  853.  
  854.   KernelErrorCode = KRERR_NO_ERROR;
  855.   tmp_ptr->ref_count = 1;
  856.   return( tmp_ptr );
  857. }
  858.  
  859.  
  860. /*****************************************************************************
  861.   FUNCTION : krm_NTableReleaseEntry
  862.  
  863.   PURPOSE  : release one name-table entry
  864.   NOTES    :
  865.  
  866.   RETURNS  :
  867.   UPDATE   : 
  868. ******************************************************************************/
  869. void    krm_NTableReleaseEntry(struct NameTable *NTable_ptr)
  870. {
  871.   --NoOfNTableEntries;
  872.  
  873.   free( NTable_ptr->Entry.symbol );
  874.   NTable_ptr->sym_type = UNUSED_SYM;
  875.   NTable_ptr->Entry.next = free_NTable_entry;
  876.   free_NTable_entry = NTable_ptr;
  877. }
  878.  
  879.  
  880. /*****************************************************************************
  881.   FUNCTION : krm_releaseNTableArrays
  882.  
  883.   PURPOSE  : release all name-table blocks
  884.   NOTES    :
  885.  
  886.   RETURNS  :
  887.   UPDATE   : 
  888. ******************************************************************************/
  889. static void  krm_releaseNTableArrays(void)
  890. {
  891.   struct NameTable     *tmp_ptr;
  892.  
  893.  
  894.   NoOfNTableEntries      = 0;
  895.   NoOfAllocNTableEntries = 0;
  896.  
  897.   if (NTable_array != NULL)  {
  898.     for (tmp_ptr = NTable_array - 1; tmp_ptr > NTable_block_list; --tmp_ptr)  {
  899.       if (tmp_ptr->sym_type != UNUSED_SYM)
  900.         free( tmp_ptr->Entry.symbol );    /*  free symbols */
  901.     }
  902.  
  903.     tmp_ptr = NTable_block_list->Entry.next;
  904.     free( (char *) NTable_block_list );
  905.     NTable_block_list = tmp_ptr;
  906.  
  907.     while (NTable_block_list != NULL)  {
  908.       for (tmp_ptr = NTable_block_list + NTABLE_BLOCK;
  909.            tmp_ptr > NTable_block_list; --tmp_ptr)  {
  910.         if (tmp_ptr->sym_type != UNUSED_SYM)
  911.           free( tmp_ptr->Entry.symbol );   /*  free symbols */
  912.       }
  913.  
  914.       tmp_ptr =  NTable_block_list->Entry.next;
  915.       free( (char *) NTable_block_list );
  916.       NTable_block_list = tmp_ptr;
  917.     }
  918.  
  919.     free_NTable_entry = NULL;
  920.     NTable_array      = NULL;
  921.   }
  922. }
  923.  
  924.  
  925. /*****************************************************************************
  926.   FUNCTION : krm_NTableSymbolSearch
  927.  
  928.   PURPOSE  : Searches for a given symbol and symbol-type in the name table.
  929.   NOTES    :
  930.  
  931.   RETURNS  : Returns symbol ptr if symbol was found, NULL otherwise.
  932.   UPDATE   : 
  933. ******************************************************************************/
  934. struct  NameTable   *krm_NTableSymbolSearch(char *symbol, int sym_type)
  935. {
  936.   int   symbol_type;
  937.   struct  NameTable   *n_ptr,
  938.                       *block_list;
  939.  
  940.  
  941.   if (NTable_array == NULL)  return( NULL );
  942.  
  943.   block_list = NTable_block_list;
  944.   for (n_ptr = NTable_array - 1; n_ptr > block_list; n_ptr--)  {
  945.     symbol_type = (int) n_ptr->sym_type;
  946.     if ( (symbol_type != UNUSED_SYM) &&
  947.          (symbol_type == sym_type) &&
  948.          (strcmp( n_ptr->Entry.symbol, symbol ) == 0) )
  949.       return( n_ptr );    /*  symbol was found    */
  950.   }
  951.  
  952.   for (block_list = block_list->Entry.next;
  953.        block_list != NULL;
  954.        block_list = block_list->Entry.next)  {
  955.     for (n_ptr = block_list + NTABLE_BLOCK; n_ptr > block_list; n_ptr--)  {
  956.       symbol_type = (int) n_ptr->sym_type;
  957.       if ( (symbol_type != UNUSED_SYM) &&
  958.            (symbol_type == sym_type) &&
  959.            (strcmp( n_ptr->Entry.symbol, symbol ) == 0) )
  960.         return( n_ptr );    /*  symbol was found    */
  961.     }
  962.   }
  963.  
  964.   return( NULL );
  965. }
  966.  
  967.  
  968. /*****************************************************************************
  969.   FUNCTION : krm_NTableCreateEntry
  970.  
  971.   PURPOSE  : Creates a new symbol in the name-table
  972.   NOTES    :
  973.  
  974.   RETURNS  : Returns name-table ptr or NULL if memory alloc has failed.
  975.   UPDATE   : 
  976. ******************************************************************************/
  977. struct NameTable  *krm_NTableCreateEntry(char *symbol_name, int symbol_type)
  978. {
  979.   char   *str_ptr;
  980.   struct  NameTable     *n_ptr;
  981.  
  982.  
  983.   KernelErrorCode = KRERR_NO_ERROR;
  984.  
  985.   if ( (n_ptr = krm_getNTableEntry() ) == NULL)
  986.     return( NULL );     /*  memory alloc failed */
  987.  
  988.   if ((str_ptr = (char *) strdup( symbol_name ) ) == NULL)
  989.     {  /*  memory alloc failed */
  990.     KernelErrorCode = KRERR_INSUFFICIENT_MEM;
  991.     return( NULL );
  992.   }
  993.  
  994.   n_ptr->Entry.symbol = str_ptr;
  995.   n_ptr->sym_type = (unsigned short) symbol_type;
  996.  
  997.   return( n_ptr );
  998. }
  999.  
  1000.  
  1001. /*****************************************************************************
  1002.   FUNCTION : krm_NTableInsertSymbol
  1003.  
  1004.   PURPOSE  : Inserts a symbol in the name-table. This function duplicates 
  1005.              symbol ptrs if the symbol was found in the name-table.
  1006.   NOTES    :
  1007.  
  1008.   RETURNS  : Returns symbol ptr or NULL if memory alloc has failed
  1009.   UPDATE   : 
  1010. ******************************************************************************/
  1011. char  *krm_NTableInsertSymbol(char *symbol_name, int symbol_type)
  1012. {
  1013.   struct NameTable  *n_ptr;
  1014.  
  1015.  
  1016.   if ( (n_ptr = krm_NTableSymbolSearch( symbol_name, symbol_type ) ) != NULL)
  1017.     {   /*  symbol is already in the name table  */
  1018.     if ((n_ptr->ref_count) < (unsigned short) MAXSHORT) {
  1019.         n_ptr->ref_count++;
  1020.     }
  1021.     return( n_ptr->Entry.symbol );
  1022.   }
  1023.  
  1024.   n_ptr = krm_NTableCreateEntry( symbol_name, symbol_type );
  1025.   return( n_ptr->Entry.symbol );
  1026. }
  1027.  
  1028.  
  1029. /*****************************************************************************
  1030.   FUNCTION : krm_NTableReleaseSymbol
  1031.  
  1032.   PURPOSE  : release name-table entry if there is no other reference to this 
  1033.              symbol
  1034.   NOTES    :
  1035.  
  1036.   RETURNS  : 
  1037.   UPDATE   : 
  1038. ******************************************************************************/
  1039. void  krm_NTableReleaseSymbol(char *symbol_name, int symbol_type)
  1040. {
  1041.   struct NameTable  *n_ptr;
  1042.  
  1043.  
  1044.   if (symbol_name == NULL)  return;
  1045.   if ( (n_ptr = krm_NTableSymbolSearch( symbol_name, symbol_type ) ) != NULL)
  1046.     {   /*  symbol is in the name table  */
  1047.     if ((n_ptr->ref_count) < (unsigned short) MAXSHORT)
  1048.       {   /*    No. of references to this symbol don't exceed the max. reference
  1049.                 count. This means it is possible to delete the symbol if the
  1050.                 reference count is zero.
  1051.           */
  1052.       if (--(n_ptr->ref_count) == 0)
  1053.         krm_NTableReleaseEntry( n_ptr );
  1054.     }
  1055.   }
  1056. }
  1057.  
  1058.  
  1059. /*****************************************************************************
  1060.   FUNCTION : krm_getNTableFirstEntry
  1061.  
  1062.   PURPOSE  : get the first name-table entry
  1063.   NOTES    :
  1064.  
  1065.   RETURNS  : the nametable 
  1066.   UPDATE   : 
  1067. ******************************************************************************/
  1068. struct NameTable       *krm_getNTableFirstEntry(void)
  1069. {
  1070.   if (NTable_array == NULL)  return( NULL );
  1071.  
  1072.   curr_NTable_block = NTable_block_list;
  1073.   curr_NTable_entry = NTable_array - 1;
  1074.   return( curr_NTable_entry );
  1075. }
  1076.  
  1077.  
  1078. /*****************************************************************************
  1079.   FUNCTION : krm_getNTableNextEntry
  1080.  
  1081.   PURPOSE  : get the next name-table entry
  1082.   NOTES    :
  1083.  
  1084.   RETURNS  : the nametable 
  1085.   UPDATE   : 
  1086. ******************************************************************************/
  1087. struct NameTable       *krm_getNTableNextEntry(void)
  1088. {
  1089.   if ((NTable_array == NULL) || (curr_NTable_block == NULL))
  1090.     return( NULL );
  1091.  
  1092.   if (--curr_NTable_entry == curr_NTable_block)  {
  1093.     if ( (curr_NTable_block = curr_NTable_block->Entry.next) == NULL)
  1094.       return( NULL );
  1095.  
  1096.     curr_NTable_entry = curr_NTable_block + NTABLE_BLOCK;
  1097.   }
  1098.  
  1099.   return( curr_NTable_entry );
  1100. }
  1101.  
  1102.  
  1103.  
  1104.  
  1105.  
  1106. /*#################################################
  1107.  
  1108. GROUP: SiteTable Functions
  1109.  
  1110. #################################################*/
  1111. /*****************************************************************************
  1112.   FUNCTION : krm_allocSTableArray
  1113.  
  1114.   PURPOSE  : allocate another site-table block
  1115.   NOTES    :
  1116.  
  1117.   RETURNS  :
  1118.   UPDATE   : 
  1119. ******************************************************************************/
  1120. static int  krm_allocSTableArray(void)
  1121. {
  1122.   STableArray     tmp_ptr;
  1123.  
  1124.  
  1125.   tmp_ptr = (STableArray) calloc( STABLE_BLOCK + 1, STABLE_SIZE );
  1126.   if (tmp_ptr == NULL)  return( 1 );
  1127.  
  1128.   if (STable_array == NULL)  {
  1129.     tmp_ptr->Entry.next = NULL;     /*  free site-table block sentinel  */
  1130.     free_STable_entry = tmp_ptr;    /*  free site-table entry sentinel  */
  1131.   }
  1132.   else  {
  1133.     tmp_ptr->Entry.next = STable_block_list;    /*  append new site-table block
  1134.                                                     to block list   */
  1135.   }
  1136.  
  1137.   STable_block_list = tmp_ptr;      /*  update block list ptr  */
  1138.   NoOfAllocSTableEntries += STABLE_BLOCK;
  1139.   STable_array = tmp_ptr + 1;       /* STable_array points to the first entry */
  1140.   return( 0 );
  1141. }
  1142.  
  1143.  
  1144. /*****************************************************************************
  1145.   FUNCTION : krm_allocSTableArray
  1146.  
  1147.   PURPOSE  : get one site-table entry
  1148.   NOTES    :
  1149.  
  1150.   RETURNS  :
  1151.   UPDATE   : 
  1152. ******************************************************************************/
  1153. static  struct SiteTable    *krm_getSTableEntry(void)
  1154. {
  1155.   struct SiteTable  *tmp_ptr;
  1156.  
  1157.  
  1158.   KernelErrorCode = KRERR_NO_ERROR;
  1159.   if ((STable_array == NULL) || (NoOfSTableEntries == NoOfAllocSTableEntries))
  1160.     if (krm_allocSTableArray() != 0)  {
  1161.       KernelErrorCode = KRERR_INSUFFICIENT_MEM;
  1162.       return( NULL );
  1163.     }
  1164.  
  1165.   NoOfSTableEntries++;
  1166.  
  1167.   if (free_STable_entry->Entry.next != NULL)
  1168.     {   /*  a previous released site-table entry is availabe    */
  1169.     tmp_ptr = free_STable_entry;
  1170.     free_STable_entry = free_STable_entry->Entry.next;
  1171.   }
  1172.   else  {
  1173.     tmp_ptr = STable_array++;
  1174.   }
  1175.  
  1176.   return( tmp_ptr );
  1177. }
  1178.  
  1179.  
  1180. /*****************************************************************************
  1181.   FUNCTION : krm_releaseSTableEntry
  1182.  
  1183.   PURPOSE  : release site table block
  1184.   NOTES    :
  1185.  
  1186.   RETURNS  :
  1187.   UPDATE   : 
  1188. ******************************************************************************/
  1189. static  void    krm_releaseSTableEntry(struct SiteTable *STable_ptr)
  1190. {
  1191.   --NoOfSTableEntries;
  1192.  
  1193.   STable_ptr->site_func  = NULL;
  1194.   STable_ptr->Entry.next = free_STable_entry;
  1195.   free_STable_entry = STable_ptr;
  1196. }
  1197.  
  1198.  
  1199. /*****************************************************************************
  1200.   FUNCTION : krm_releaseSTableArrays
  1201.  
  1202.   PURPOSE  : release all site-table blocks
  1203.   NOTES    :
  1204.  
  1205.   RETURNS  :
  1206.   UPDATE   : 
  1207. ******************************************************************************/
  1208. static  void    krm_releaseSTableArrays(void)
  1209. {
  1210.   struct SiteTable     *tmp_ptr;
  1211.  
  1212.  
  1213.   NoOfSTableEntries      = 0;
  1214.   NoOfAllocSTableEntries = 0;
  1215.  
  1216.   if (STable_array != NULL)  {
  1217.     while (STable_block_list != NULL)  {
  1218.       tmp_ptr =  STable_block_list->Entry.next;
  1219.       free( (char *) STable_block_list );
  1220.       STable_block_list = tmp_ptr;
  1221.     }
  1222.  
  1223.     free_STable_entry = NULL;
  1224.     STable_array      = NULL;
  1225.   }
  1226. }
  1227.  
  1228.  
  1229. /*****************************************************************************
  1230.   FUNCTION : krm_STableCreateEntry
  1231.  
  1232.   PURPOSE  : create new site-table entry
  1233.   NOTES    :
  1234.  
  1235.   RETURNS  :
  1236.   UPDATE   : 
  1237. ******************************************************************************/
  1238. struct SiteTable *krm_STableCreateEntry(char *site_symbol, 
  1239.                     SiteFuncPtr site_func)
  1240. {
  1241.   struct  NameTable     *n_ptr;
  1242.   struct  SiteTable     *s_ptr;
  1243.  
  1244.  
  1245.   if ( (s_ptr = krm_getSTableEntry() ) == NULL)
  1246.     return( NULL );     /*  memory alloc failed */
  1247.  
  1248.   if ((n_ptr = krm_NTableCreateEntry( site_symbol, SITE_SYM ) ) == NULL)  {
  1249.     krm_releaseSTableEntry( s_ptr );
  1250.     return( NULL );     /*  memory alloc failed */
  1251.   }
  1252.  
  1253.   s_ptr->Entry.site_name = n_ptr;
  1254.   s_ptr->site_func       = site_func;
  1255.  
  1256.   return( s_ptr );
  1257. }
  1258.  
  1259.  
  1260. /*****************************************************************************
  1261.   FUNCTION : krm_STableChangeEntry
  1262.  
  1263.   PURPOSE  : change the properties of the given site-table entry
  1264.   NOTES    :
  1265.  
  1266.   RETURNS  :
  1267.   UPDATE   : 
  1268. ******************************************************************************/
  1269. struct  SiteTable   *krm_STableChangeEntry(struct SiteTable *stbl_ptr, 
  1270.                        char *new_site_name, 
  1271.                        SiteFuncPtr new_site_func)
  1272. {
  1273.   struct  NameTable     *n_ptr;
  1274.  
  1275.  
  1276.   if ((n_ptr = krm_NTableCreateEntry( new_site_name, SITE_SYM ) ) == NULL)
  1277.     return( NULL );     /*  memory alloc failed */
  1278.  
  1279.   krm_NTableReleaseEntry( stbl_ptr->Entry.site_name );
  1280.  
  1281.   stbl_ptr->Entry.site_name = n_ptr;
  1282.   stbl_ptr->site_func       = new_site_func;
  1283.  
  1284.   return( stbl_ptr );
  1285. }
  1286.  
  1287.  
  1288. /*****************************************************************************
  1289.   FUNCTION : krm_STableRemoveEntry
  1290.  
  1291.   PURPOSE  : release a previosly defined site-table entry
  1292.   NOTES    :
  1293.  
  1294.   RETURNS  :
  1295.   UPDATE   : 
  1296. ******************************************************************************/
  1297. void    krm_STableRemoveEntry(struct SiteTable *STable_ptr)
  1298. {
  1299.   krm_NTableReleaseEntry( STable_ptr->Entry.site_name );
  1300.   krm_releaseSTableEntry( STable_ptr );
  1301. }
  1302.  
  1303.  
  1304. /*****************************************************************************
  1305.   FUNCTION : krm_STableSymbolSearch
  1306.  
  1307.   PURPOSE  : searches for a symbol in the site-table
  1308.   NOTES    :
  1309.  
  1310.   RETURNS  :
  1311.   UPDATE   : 
  1312. ******************************************************************************/
  1313. struct SiteTable    *krm_STableSymbolSearch(char *site_symbol)
  1314. {
  1315.   struct  NameTable   *n_ptr;
  1316.   struct  SiteTable   *s_ptr,
  1317.                       *block_list;
  1318.  
  1319.  
  1320.   if (STable_array == NULL)
  1321.     return( NULL );     /*  there are no site-table entries */
  1322.  
  1323.   if ( (n_ptr = krm_NTableSymbolSearch( site_symbol , SITE_SYM ) ) == NULL)
  1324.     return( NULL );     /*  symbol dosn't exist */
  1325.  
  1326.  
  1327.   block_list = STable_block_list;
  1328.   for (s_ptr = STable_array - 1; s_ptr > block_list; s_ptr--)
  1329.     if ( (s_ptr->site_func != NULL) &&
  1330.          (s_ptr->Entry.site_name == n_ptr ) )
  1331.       return( s_ptr );
  1332.  
  1333.   for (block_list = block_list->Entry.next;
  1334.        block_list != NULL;
  1335.        block_list = block_list->Entry.next)  {
  1336.     for (s_ptr = block_list + STABLE_BLOCK; s_ptr > block_list; s_ptr--)
  1337.       if ( (s_ptr->site_func != NULL) &&
  1338.            (s_ptr->Entry.site_name == n_ptr ) )
  1339.         return( s_ptr );
  1340.   }
  1341.  
  1342.   return( NULL );  /*  the site symbol is in the name table, but not in 
  1343.                the site table: Error */
  1344. }
  1345.  
  1346.  
  1347. /*****************************************************************************
  1348.   FUNCTION : krm_getSTableNextRawEntry
  1349.  
  1350.   PURPOSE  : 
  1351.   NOTES    :
  1352.  
  1353.   RETURNS  : returns a pointer to the next (used or unused) site-table entry
  1354.   UPDATE   : 
  1355. ******************************************************************************/
  1356. static struct SiteTable       *krm_getSTableNextRawEntry(void)
  1357. {
  1358.   if ((STable_array == NULL) || (curr_STable_block == NULL))
  1359.     return( NULL );
  1360.  
  1361.   if (--curr_STable_entry == curr_STable_block)
  1362.     {  /*  get new site-table block  */
  1363.     if ( (curr_STable_block = curr_STable_block->Entry.next) == NULL)  {
  1364.       curr_STable_block = NULL;
  1365.       curr_STable_entry = NULL;
  1366.  
  1367.       return( NULL );
  1368.     }
  1369.  
  1370.     /* next site-table block  */
  1371.     curr_STable_entry = curr_STable_block + STABLE_BLOCK; 
  1372.   }
  1373.  
  1374.   return( curr_STable_entry );
  1375. }
  1376.  
  1377.  
  1378. /*****************************************************************************
  1379.   FUNCTION : krm_getSTableNextEntry
  1380.  
  1381.   PURPOSE  : 
  1382.   NOTES    :
  1383.  
  1384.   RETURNS  : returns a pointer to the next used site-table entry
  1385.   UPDATE   : 
  1386. ******************************************************************************/
  1387. struct SiteTable       *krm_getSTableNextEntry(void)
  1388. {
  1389.   struct  SiteTable   *stbl_ptr;
  1390.  
  1391.  
  1392.   if ((stbl_ptr = krm_getSTableNextRawEntry()) == NULL)
  1393.     return( NULL );
  1394.  
  1395.   while ( stbl_ptr->site_func == NULL) /* return only used site-table entries */
  1396.     if ((stbl_ptr = krm_getSTableNextRawEntry()) == NULL)
  1397.       return( NULL );
  1398.         
  1399.   return( stbl_ptr );
  1400. }
  1401.  
  1402.  
  1403. /*****************************************************************************
  1404.   FUNCTION : krm_getSTableFirstEntry
  1405.  
  1406.   PURPOSE  : 
  1407.   NOTES    :
  1408.  
  1409.   RETURNS  : returns a pointer to the first used site-table entry
  1410.   UPDATE   : 
  1411. ******************************************************************************/
  1412. struct SiteTable       *krm_getSTableFirstEntry(void)
  1413. {
  1414.   struct  SiteTable   *stbl_ptr;
  1415.   
  1416.  
  1417.   if (STable_array == NULL)  return( NULL );
  1418.  
  1419.   curr_STable_block = STable_block_list;
  1420.   curr_STable_entry = STable_array - 1;
  1421.   stbl_ptr = curr_STable_entry;
  1422.  
  1423.   if (stbl_ptr->site_func == NULL)  /*    return only used site-table entries  */
  1424.     if ((stbl_ptr = krm_getSTableNextEntry()) == NULL)
  1425.       return( NULL );
  1426.  
  1427.   return( stbl_ptr );
  1428. }
  1429.  
  1430.  
  1431.  
  1432.  
  1433.  
  1434. /*#################################################
  1435.  
  1436. GROUP: Ftype entry functions
  1437.  
  1438. #################################################*/
  1439.  
  1440. /*****************************************************************************
  1441.   FUNCTION : krm_getFtypeEntry
  1442.  
  1443.   PURPOSE  : allocate a new Ftype entry
  1444.   NOTES    :
  1445.  
  1446.   RETURNS  :
  1447.   UPDATE   : 
  1448. ******************************************************************************/
  1449. struct FtypeUnitStruct  *krm_getFtypeEntry(void)
  1450. {
  1451.   struct FtypeUnitStruct  *Ftype_entry;
  1452.  
  1453.  
  1454.   KernelErrorCode = KRERR_NO_ERROR;
  1455.   if ((Ftype_entry = 
  1456.            (struct FtypeUnitStruct *) malloc( FTYPE_UNIT_SIZE ) ) == NULL)
  1457.     {  /*  memory alloc failed */
  1458.     KernelErrorCode = KRERR_INSUFFICIENT_MEM;
  1459.     return( NULL );
  1460.   }
  1461.  
  1462.   if (Ftype_list_root != NULL)  {
  1463.     Ftype_list_root->prev = Ftype_entry;
  1464.     Ftype_entry->next = Ftype_list_root;
  1465.   }
  1466.   else
  1467.     Ftype_entry->next = NULL;
  1468.  
  1469.   Ftype_list_root   = Ftype_entry;
  1470.   Ftype_entry->prev = NULL;
  1471.  
  1472.   Ftype_entry->sites = NULL;
  1473.   Ftype_entry->Ftype_symbol = NULL;
  1474.  
  1475.   ++NoOfFTableEntries;
  1476.  
  1477.   return( Ftype_entry );
  1478. }
  1479.  
  1480.  
  1481. /*****************************************************************************
  1482.   FUNCTION : krm_releaseFtypeEntry
  1483.  
  1484.   PURPOSE  : free a previosly defined Ftype entry
  1485.   NOTES    :
  1486.  
  1487.   RETURNS  :
  1488.   UPDATE   : 
  1489. ******************************************************************************/
  1490. void    krm_releaseFtypeEntry(struct FtypeUnitStruct *Ftype_entry)
  1491. {
  1492.   struct  FtypeUnitStruct   *next_entry,
  1493.                             *prev_entry;
  1494.  
  1495.  
  1496.   /*  release sites first */
  1497.   if ( Ftype_entry->sites != NULL)
  1498.     krm_releaseAllSites( Ftype_entry->sites );
  1499.  
  1500.   /*  release Ftype symbol name */
  1501.   if ( Ftype_entry->Ftype_symbol != NULL )
  1502.     krm_NTableReleaseEntry( Ftype_entry->Ftype_symbol );
  1503.  
  1504.   next_entry = Ftype_entry->next;
  1505.   prev_entry = Ftype_entry->prev;
  1506.  
  1507.   if (prev_entry != NULL)
  1508.     prev_entry->next = next_entry;
  1509.   else
  1510.     Ftype_list_root = next_entry;
  1511.  
  1512.   if (next_entry != NULL)
  1513.     next_entry->prev = prev_entry;
  1514.  
  1515.   /*  release unit entry  */
  1516.   free( (char *) Ftype_entry );       /*  release Ftype entry   */
  1517.  
  1518.   --NoOfFTableEntries;
  1519. }
  1520.  
  1521. /*****************************************************************************
  1522.   FUNCTION : krm_FtypeCreateEntry
  1523.  
  1524.   PURPOSE  : create and define a Ftype entry
  1525.   NOTES    :
  1526.  
  1527.   RETURNS  : the ftype
  1528.   UPDATE   : 
  1529. ******************************************************************************/
  1530. struct FtypeUnitStruct  *krm_FtypeCreateEntry(char *Ftype_symbol, 
  1531.                           OutFuncPtr out_func, 
  1532.                           ActFuncPtr act_func, 
  1533.                           ActDerivFuncPtr act_deriv_func)
  1534. {
  1535.   struct  FtypeUnitStruct   *Ftype_entry;
  1536.   struct  NameTable         *n_ptr;
  1537.  
  1538.  
  1539.   if ( (Ftype_entry = krm_getFtypeEntry() ) == NULL)
  1540.     return( NULL );     /*  memory alloc failed */
  1541.  
  1542.   if((n_ptr = krm_NTableCreateEntry( Ftype_symbol, FTYPE_UNIT_SYM ) ) == NULL) {
  1543.     krm_releaseFtypeEntry( Ftype_entry );
  1544.     return( NULL );     /*  memory alloc failed */
  1545.   }
  1546.  
  1547.   Ftype_entry->Ftype_symbol = n_ptr;
  1548.   Ftype_entry->out_func = out_func;
  1549.   Ftype_entry->act_func = act_func;
  1550.   Ftype_entry->act_deriv_func = act_deriv_func;
  1551.   Ftype_entry->sites = NULL;
  1552.  
  1553.   return( Ftype_entry );
  1554. }
  1555.  
  1556.  
  1557. /*****************************************************************************
  1558.   FUNCTION : krm_FtypeAddSite
  1559.  
  1560.   PURPOSE  : add a site to a previosly defined Ftype entry
  1561.   NOTES    :
  1562.  
  1563.   RETURNS  : the site
  1564.   UPDATE   : 
  1565. ******************************************************************************/
  1566. struct Site  *krm_FtypeAddSite(struct FtypeUnitStruct *Ftype_entry, 
  1567.                    struct SiteTable *STable_entry)
  1568. {
  1569.   struct  Site   *site_ptr;
  1570.  
  1571.  
  1572.   if ( (site_ptr = krm_getFtypeSite() ) == NULL)
  1573.     return( NULL );     /*  memory alloc failed */
  1574.  
  1575.   site_ptr->next = Ftype_entry->sites;
  1576.   Ftype_entry->sites = site_ptr;
  1577.  
  1578.   site_ptr->site_table = STable_entry;
  1579.  
  1580.   return( site_ptr );
  1581. }
  1582.  
  1583.  
  1584. /*****************************************************************************
  1585.   FUNCTION : krm_getFtypeFirstEntry
  1586.  
  1587.   PURPOSE  : 
  1588.   NOTES    :
  1589.  
  1590.   RETURNS  : returns a pointer to first Ftype entry
  1591.   UPDATE   : 
  1592. ******************************************************************************/
  1593. struct FtypeUnitStruct  *krm_getFtypeFirstEntry(void)
  1594. {
  1595.   curr_Ftype_entry = Ftype_list_root;
  1596.   return( Ftype_list_root );
  1597. }
  1598.  
  1599.  
  1600. /*****************************************************************************
  1601.   FUNCTION : krm_getFtypeNextEntry
  1602.  
  1603.   PURPOSE  : 
  1604.   NOTES    :
  1605.  
  1606.   RETURNS  : returns a pointer to next Ftype entry
  1607.   UPDATE   : 
  1608. ******************************************************************************/
  1609. struct FtypeUnitStruct  *krm_getFtypeNextEntry(void)
  1610. {
  1611.   if (curr_Ftype_entry != NULL)  {
  1612.     if (curr_Ftype_entry->next != NULL)
  1613.       curr_Ftype_entry = curr_Ftype_entry->next;
  1614.     else
  1615.       return( NULL );
  1616.   }
  1617.  
  1618.   return( curr_Ftype_entry );
  1619. }
  1620.  
  1621.  
  1622. /*****************************************************************************
  1623.   FUNCTION : krm_getFtypeNextEntry
  1624.  
  1625.   PURPOSE  : searches for a Ftype entry with the given name
  1626.   NOTES    :
  1627.  
  1628.   RETURNS  :
  1629.   UPDATE   : 
  1630. ******************************************************************************/
  1631. struct  FtypeUnitStruct  *krm_FtypeSymbolSearch(char *Ftype_symbol)
  1632. {
  1633.   struct  FtypeUnitStruct   *ftype_entry;
  1634.  
  1635.  
  1636.   if (Ftype_symbol == NULL)  return( NULL);
  1637.  
  1638.   ftype_entry = Ftype_list_root;
  1639.   while (ftype_entry != NULL)  {
  1640.     if (strcmp( Ftype_symbol, (ftype_entry->Ftype_symbol)->Entry.symbol ) == 0)
  1641.       return( ftype_entry );
  1642.  
  1643.     ftype_entry = ftype_entry->next;
  1644.   }
  1645.  
  1646.   return( NULL );
  1647. }
  1648.  
  1649.  
  1650. /*****************************************************************************
  1651.   FUNCTION : krm_releaseFtypeList
  1652.  
  1653.   PURPOSE  : releases all Ftype entries
  1654.   NOTES    :
  1655.  
  1656.   RETURNS  :
  1657.   UPDATE   : 
  1658. ******************************************************************************/
  1659. void    krm_releaseFtypeList(void)
  1660. {
  1661.   struct  FtypeUnitStruct   *Ftype_entry,
  1662.                             *ft_ptr;
  1663.  
  1664.  
  1665.   Ftype_entry = Ftype_list_root;
  1666.  
  1667.   while( Ftype_entry != NULL )  {
  1668.     /*  release sites first */
  1669.     if ( Ftype_entry->sites != NULL)
  1670.       krm_releaseAllFtypeSites( Ftype_entry->sites );
  1671.  
  1672.     /*  release Ftype symbol name */
  1673.     if ( Ftype_entry->Ftype_symbol != NULL )
  1674.       krm_NTableReleaseEntry( Ftype_entry->Ftype_symbol );
  1675.  
  1676.     ft_ptr = Ftype_entry;
  1677.     Ftype_entry = Ftype_entry->next;
  1678.     /*  release unit entry  */
  1679.     free( (char *) ft_ptr );       /*  release Ftype entry   */
  1680.   }
  1681.  
  1682.   Ftype_list_root = NULL;
  1683.   NoOfFTableEntries = 0;
  1684. }
  1685.  
  1686.  
  1687.  
  1688. #ifdef MASPAR_KERNEL
  1689. #ifdef MASPAR_KERNEL_EMULATION
  1690.  
  1691. /*#################################################
  1692.  
  1693. GROUP: Functions for the MasPar kernel
  1694.  
  1695. #################################################*/
  1696. /*****************************************************************************
  1697.   FUNCTION : krm_releaseWeightArrays
  1698.  
  1699.   PURPOSE  : release weight arrays from memory
  1700.   NOTES    :
  1701.  
  1702.   RETURNS  :
  1703.   UPDATE   : 
  1704. ******************************************************************************/
  1705. void  krm_releaseWeightArrays(void)
  1706. {
  1707.   int  dest_layer, src_layer;
  1708.   FlintType  *weight_array;
  1709.  
  1710.   /*  get weight array pointers  */
  1711.   for (dest_layer = 1; dest_layer < descrFFnet.no_of_layers; dest_layer++)
  1712.     for (src_layer = 0; src_layer < dest_layer; src_layer++)  {
  1713.       weight_array = 
  1714.       descrFFnet.layers[dest_layer].inputs[src_layer].weight_array;
  1715.       if (weight_array != NULL)  {
  1716.         free( (char *) weight_array );
  1717.     descrFFnet.layers[ dest_layer ].inputs[src_layer].weight_array = NULL;
  1718.     descrFFnet.layers[ dest_layer ].inputs[src_layer].no_of_inputs = 0;
  1719.       }
  1720.     }
  1721.  
  1722.   NoOfWeights = 0;
  1723.   specialNetworkType == NET_TYPE_GENERAL;
  1724. }
  1725.  
  1726.  
  1727. /*****************************************************************************
  1728.   FUNCTION :  krm_createWeightArrays
  1729.  
  1730.   PURPOSE  :  creates arrays containing connection weights for feedforward 
  1731.               networks
  1732.   NOTES    :
  1733.  
  1734.   RETURNS  :
  1735.   UPDATE   : 
  1736. ******************************************************************************/
  1737. krui_err  krm_createWeightArrays(void)
  1738. {
  1739.   int  dest_layer, src_layer, no_of_inputs;
  1740.   FlintType  *weight_array;
  1741.  
  1742.   KernelErrorCode = KRERR_NO_ERROR;
  1743.   NoOfWeights = 0;
  1744.  
  1745.   /*  allocate weight arrays  */
  1746.   for (dest_layer = 1; dest_layer < descrFFnet.no_of_layers; dest_layer++)
  1747.     for (src_layer = 0; src_layer < dest_layer; src_layer++)  {
  1748.     no_of_inputs = 
  1749.         descrFFnet.layers[ dest_layer ].inputs[src_layer].no_of_inputs;
  1750.       if (no_of_inputs > 0)
  1751.         {  /*  there are <no_of_inputs> connections between layer <src_layer>
  1752.                and layer <dest_layer>.  */
  1753.     weight_array = (FlintType *) calloc( no_of_inputs, sizeof (FlintType) );
  1754.         if (weight_array == NULL)
  1755.           {  /*  insufficient memory  */
  1756.           KernelErrorCode = KRERR_INSUFFICIENT_MEM;
  1757.           krm_releaseWeightArrays();
  1758.           return( KernelErrorCode );
  1759.         }
  1760.  
  1761.     descrFFnet.layers[dest_layer].inputs[src_layer].weight_array = 
  1762.         weight_array;
  1763.       }
  1764.     }
  1765.  
  1766.   NoOfWeights = descrFFnet.no_of_weights;
  1767.   return( KernelErrorCode );
  1768. }
  1769.  
  1770. #endif
  1771. #endif
  1772.  
  1773.  
  1774.  
  1775. /*#################################################
  1776.  
  1777. GROUP: Memory cleanup
  1778.  
  1779. #################################################*/
  1780. /*****************************************************************************
  1781.   FUNCTION :  krm_releaseMem
  1782.  
  1783.   PURPOSE  :  frees all memory used for the internal representation of the 
  1784.               network
  1785.   NOTES    :
  1786.  
  1787.   RETURNS  :
  1788.   UPDATE   : 
  1789. ******************************************************************************/
  1790. void    krm_releaseMem(void)
  1791. {
  1792. #ifdef MASPAR_KERNEL
  1793. #ifdef MASPAR_KERNEL_EMULATION
  1794.  
  1795.   if (specialNetworkType == NET_TYPE_FF1)
  1796.     krm_releaseWeightArrays();
  1797.  
  1798. #endif
  1799. #endif
  1800.  
  1801.   specialNetworkType = NET_TYPE_GENERAL;
  1802.   krm_releaseFtypeList();
  1803.   krm_releaseSTableArrays();
  1804.   krm_releaseNTableArrays();
  1805.   krm_releaseLinkArrays();
  1806.   krm_releaseSiteArrays();
  1807.   krm_releaseUnitArrays();
  1808.   krm_releaseUnitTopoArray();
  1809.  
  1810. #ifdef KERNEL3D
  1811.   if (transTable != NULL)  {
  1812.     free( (void *) transTable );
  1813.     transTable = NULL;
  1814.     transTableSize = 0;
  1815.   }
  1816. #endif
  1817.  
  1818. }
  1819.  
  1820.  
  1821. /*  ---------------------  End of Memory Management Functions  -------------  */
  1822.